# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
#     https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
#     https://docs.fastlane.tools/plugins/available-plugins
#

# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane

default_platform(:android)

platform :android do
  desc "Runs all the tests"
  lane :test do
    Dir.chdir("../src/android") do
      sh("../../gradlew", "test")
    end
  end

  desc "Build a new version for internal testing"
  lane :build_internal do
    UI.important("🔍 Validating build configuration...")

    # Validate environment variables
    validate_signing_config({})

    # Check if Flutter-generated AAB exists
    aab_path = File.expand_path('../src/build/app/outputs/bundle/release/app-release.aab', __dir__)
    unless File.exist?(aab_path)
      UI.error("❌ Flutter-generated AAB not found at: #{aab_path}")
      UI.error("Please ensure 'flutter build appbundle --release' was executed successfully")
      raise "AAB file not found"
    end

    UI.success("✅ Flutter-generated AAB found: #{aab_path}")

    # Get AAB file size for validation
    aab_size = File.size(aab_path)
    UI.important("📦 AAB file size: #{format_bytes(aab_size)}")

    if aab_size < 1_000_000 # Less than 1MB is suspicious
      UI.error("⚠️ AAB file size seems too small (#{format_bytes(aab_size)}), please verify the build")
    end

    UI.success("✅ Build validation completed successfully")
  end

  desc "Deploy a new version to the Google Play internal testing track"
  lane :deploy_internal do
    build_internal

    metadata_opts = metadata_options

    upload_to_play_store(
      track: 'internal',
      aab: File.expand_path('../src/build/app/outputs/bundle/release/app-release.aab', __dir__),
      json_key: ENV["GOOGLE_PLAY_SERVICE_ACCOUNT_KEY"],
      skip_upload_apk: true,
      skip_upload_images: true,
      skip_upload_screenshots: true,
      release_status: 'completed',
      **metadata_opts
    )
  end

  desc "Deploy a new version to the Google Play alpha track"
  lane :deploy_alpha do
    build_internal

    metadata_opts = metadata_options

    upload_to_play_store(
      track: 'alpha',
      aab: File.expand_path('../src/build/app/outputs/bundle/release/app-release.aab', __dir__),
      json_key: ENV["GOOGLE_PLAY_SERVICE_ACCOUNT_KEY"],
      skip_upload_apk: true,
      skip_upload_images: true,
      skip_upload_screenshots: true,
      release_status: 'completed',
      **metadata_opts
    )
  end

  desc "Deploy a new version to the Google Play beta track"
  lane :deploy_beta do
    build_internal

    metadata_opts = metadata_options

    upload_to_play_store(
      track: 'beta',
      aab: File.expand_path('../src/build/app/outputs/bundle/release/app-release.aab', __dir__),
      json_key: ENV["GOOGLE_PLAY_SERVICE_ACCOUNT_KEY"],
      skip_upload_apk: true,
      skip_upload_images: true,
      skip_upload_screenshots: true,
      release_status: 'completed',
      **metadata_opts
    )
  end

  desc "Deploy a new version to the Google Play production track"
  lane :deploy_production do
    build_internal

    metadata_opts = metadata_options

    upload_to_play_store(
      track: 'production',
      aab: File.expand_path('../src/build/app/outputs/bundle/release/app-release.aab', __dir__),
      json_key: ENV["GOOGLE_PLAY_SERVICE_ACCOUNT_KEY"],
      skip_upload_apk: true,
      skip_upload_images: true,
      skip_upload_screenshots: true,
      release_status: 'completed',
      rollout: '0.1', # Start with 10% rollout for production
      **metadata_opts
    )
  end

  desc "Deploy a new version to the Google Play production track with full rollout"
  lane :deploy_production_full do
    build_internal

    metadata_opts = metadata_options

    upload_to_play_store(
      track: 'production',
      aab: File.expand_path('../src/build/app/outputs/bundle/release/app-release.aab', __dir__),
      json_key: ENV["GOOGLE_PLAY_SERVICE_ACCOUNT_KEY"],
      skip_upload_apk: true,
      skip_upload_images: true,
      skip_upload_screenshots: true,
      release_status: 'completed',
      rollout: '1.0', # Full rollout
      **metadata_opts
    )
  end

  desc "Update metadata for Google Play Store"
  lane :update_metadata do
    metadata_opts = metadata_options(require_metadata: true)

    upload_to_play_store(
      track: 'production',
      json_key: ENV["GOOGLE_PLAY_SERVICE_ACCOUNT_KEY"],
      skip_upload_apk: true,
      skip_upload_aab: true,
      skip_upload_images: false,
      skip_upload_screenshots: false,
      **metadata_opts
    )
  end

  desc "Promote from internal to alpha track"
  lane :promote_to_alpha do
    upload_to_play_store(
      track: 'alpha',
      json_key: ENV["GOOGLE_PLAY_SERVICE_ACCOUNT_KEY"],
      skip_upload_apk: true,
      skip_upload_aab: true,
      skip_upload_metadata: true,
      skip_upload_images: true,
      skip_upload_screenshots: true,
      from_track: 'internal',
      promote_track: 'alpha',
      release_status: 'completed'
    )
  end

  desc "Promote from alpha to beta track"
  lane :promote_to_beta do
    upload_to_play_store(
      track: 'beta',
      json_key: ENV["GOOGLE_PLAY_SERVICE_ACCOUNT_KEY"],
      skip_upload_apk: true,
      skip_upload_aab: true,
      skip_upload_metadata: true,
      skip_upload_images: true,
      skip_upload_screenshots: true,
      from_track: 'alpha',
      promote_track: 'beta',
      release_status: 'completed'
    )
  end

  desc "Promote from beta to production track"
  lane :promote_to_production do
    upload_to_play_store(
      track: 'production',
      json_key: ENV["GOOGLE_PLAY_SERVICE_ACCOUNT_KEY"],
      skip_upload_apk: true,
      skip_upload_aab: true,
      skip_upload_metadata: true,
      skip_upload_images: true,
      skip_upload_screenshots: true,
      from_track: 'beta',
      promote_track: 'production',
      release_status: 'completed',
      rollout: '0.1' # Start with 10% rollout
    )
  end

  desc "Increase production rollout percentage"
  lane :increase_rollout do
    # Get current rollout status
    current_rollout = get_current_rollout_percentage
    
    # Calculate next rollout step
    next_rollout = calculate_next_rollout(current_rollout)
    
    upload_to_play_store(
      track: 'production',
      json_key: ENV["GOOGLE_PLAY_SERVICE_ACCOUNT_KEY"],
      skip_upload_apk: true,
      skip_upload_aab: true,
      skip_upload_metadata: true,
      skip_upload_images: true,
      skip_upload_screenshots: true,
      rollout: next_rollout.to_s,
      release_status: 'completed'
    )
    
    UI.message("Rollout increased from #{current_rollout * 100}% to #{next_rollout * 100}%")
  end

  desc "Halt production rollout"
  lane :halt_rollout do
    upload_to_play_store(
      track: 'production',
      json_key: ENV["GOOGLE_PLAY_SERVICE_ACCOUNT_KEY"],
      skip_upload_apk: true,
      skip_upload_aab: true,
      skip_upload_metadata: true,
      skip_upload_images: true,
      skip_upload_screenshots: true,
      rollout: '0.0',
      release_status: 'halted'
    )
  end

  desc "Resume production rollout"
  lane :resume_rollout do
    upload_to_play_store(
      track: 'production',
      json_key: ENV["GOOGLE_PLAY_SERVICE_ACCOUNT_KEY"],
      skip_upload_apk: true,
      skip_upload_aab: true,
      skip_upload_metadata: true,
      skip_upload_images: true,
      skip_upload_screenshots: true,
      release_status: 'completed'
    )
  end

  # Error handling
  error do |lane, exception|
    UI.error("❌ Lane #{lane} failed with exception: #{exception}")
    UI.error("📍 Backtrace: #{exception.backtrace.join("\n")}")

    # Provide helpful troubleshooting information
    case lane
    when :deploy_internal, :build_internal
      UI.important("🔧 Troubleshooting tips for build failures:")
      UI.important("1. Verify Flutter build completed successfully")
      UI.important("2. Check signing configuration in key.properties")
      UI.important("3. Ensure keystore file exists and is accessible")
      UI.important("4. Verify environment variables are set correctly")
    else
      UI.important("🔧 Check Fastlane configuration and Google Play credentials")
    end
  end

  private_lane :extract_changelog do
    # Get version from pubspec.yaml
    pubspec_path = File.join(Dir.pwd, '..', 'src', 'pubspec.yaml')
    version_line = File.readlines(pubspec_path).find { |line| line.match(/^version:/) }
    version = version_line.split(' ')[1].strip
    
    # Extract version number (without build number)
    version_number = version.split('+')[0]
    
    # Look for changelog in metadata directory
    changelog_path = File.join(Dir.pwd, 'metadata', 'android', 'en-US', 'changelogs', "#{version_number}.txt")
    
    if File.exist?(changelog_path)
      File.read(changelog_path).strip
    else
      # Fallback to generic changelog
      "Bug fixes and performance improvements for version #{version_number}"
    end
  end

  def self.metadata_options(require_metadata: false)
    metadata_dir = File.expand_path('../metadata/android', __dir__)

    if Dir.exist?(metadata_dir)
      UI.message("📄 Metadata directory detected at #{metadata_dir}")
      {
        skip_upload_metadata: false,
        metadata_path: metadata_dir
      }
    elsif require_metadata
      UI.user_error!("Metadata directory not found at #{metadata_dir}. Provide Google Play Store metadata or create the directory before running this lane.")
    else
      UI.important("ℹ️ Metadata directory not found at #{metadata_dir}, skipping metadata upload")
      {
        skip_upload_metadata: true
      }
    end
  end

  private_lane :get_current_rollout_percentage do
    # This would require additional API calls to get current rollout status
    # For now, return a default value
    0.1
  end

  private_lane :calculate_next_rollout do |current_rollout|
    case current_rollout
    when 0.1
      0.2
    when 0.2
      0.5
    when 0.5
      1.0
    else
      1.0
    end
  end

  # Validate signing configuration
  private_lane :validate_signing_config do
    UI.important("🔐 Validating signing configuration...")

    required_vars = %w[KEYSTORE_FILE_PATH KEYSTORE_PASSWORD KEY_ALIAS KEY_PASSWORD GOOGLE_PLAY_SERVICE_ACCOUNT_KEY]
    missing_vars = required_vars.select { |var| ENV[var].nil? || ENV[var].empty? }

    unless missing_vars.empty?
      UI.error("❌ Missing required environment variables: #{missing_vars.join(', ')}")
      raise "Missing signing configuration"
    end

    # Validate keystore file exists
    keystore_path = ENV["KEYSTORE_FILE_PATH"]
    unless File.exist?(keystore_path)
      UI.error("❌ Keystore file not found: #{keystore_path}")
      raise "Keystore file not found"
    end

    # Validate Google Play service account file exists
    service_account_path = ENV["GOOGLE_PLAY_SERVICE_ACCOUNT_KEY"]
    unless File.exist?(service_account_path)
      UI.error("❌ Google Play service account file not found: #{service_account_path}")
      raise "Service account file not found"
    end

    # Validate keystore file size (should be more than a few KB)
    keystore_size = File.size(keystore_path)
    if keystore_size < 1024
      UI.error("⚠️ Keystore file seems too small: #{format_bytes(keystore_size)}")
    end

    UI.success("✅ Signing configuration validated successfully")
    UI.important("📁 Keystore: #{keystore_path} (#{format_bytes(keystore_size)})")
    UI.important("🔑 Key Alias: #{ENV["KEY_ALIAS"]}")
    UI.important("📄 Service Account: #{service_account_path}")
  end

  # Format bytes for human readable output
  def self.format_bytes(bytes)
    units = ['B', 'KB', 'MB', 'GB']
    size = bytes.to_f
    unit_index = 0

    while size >= 1024 && unit_index < units.length - 1
      size /= 1024
      unit_index += 1
    end

    "#{size.round(2)} #{units[unit_index]}"
  end

  # Validate AAB file integrity
  private_lane :validate_aab_file do |aab_path|
    UI.important("🔍 Validating AAB file integrity...")

    unless File.exist?(aab_path)
      UI.error("❌ AAB file not found: #{aab_path}")
      raise "AAB file not found"
    end

    # Check file size
    file_size = File.size(aab_path)
    UI.important("📦 AAB file size: #{format_bytes(file_size)}")

    if file_size < 1_000_000 # Less than 1MB
      UI.error("⚠️ AAB file size seems too small: #{format_bytes(file_size)}")
      raise "AAB file too small"
    end

    if file_size > 200_000_000 # More than 200MB
      UI.error("⚠️ AAB file size seems too large: #{format_bytes(file_size)}")
      raise "AAB file too large"
    end

    # Check file extension
    unless aab_path.end_with?('.aab')
      UI.error("❌ Invalid file extension. Expected .aab file")
      raise "Invalid file extension"
    end

    UI.success("✅ AAB file validation passed")
  end
end